﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.DB.ExtensibleStorage;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using DBService;
using YArchitech.Revit.RevitExtension;

namespace YArchitech.Revit.MEP.Opening.Common
{
	internal class CmdTools
	{
		public static void Debug(string msg)
		{
			Console.WriteLine(msg);
		}

		public static void MsgBox(string msg)
		{
		}

		public static FamilySymbol GetOpeningSymbol(Autodesk.Revit.DB.Document doc)
		{
			FamilySymbol result = null;
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(Family)).ToElements())
			{
				Family family = element as Family;
				if (family != null && family.Name == "盈建科MEP开洞检测")
				{
					using (List<FamilySymbol>.Enumerator enumerator2 = family.GetSymbols().GetEnumerator())
					{
						while (enumerator2.MoveNext())
						{
							FamilySymbol familySymbol = enumerator2.Current;
							if (familySymbol.Name == "开洞标记")
							{
								result = familySymbol;
								break;
							}
						}
						break;
					}
				}
			}
			return result;
		}

		public static FamilySymbol GetBallSymbol(Autodesk.Revit.DB.Document doc)
		{
			FamilySymbol result = null;
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(Family)).ToElements())
			{
				Family family = element as Family;
				if (family != null && family.Name == "盈建科MEP开洞标记")
				{
					using (List<FamilySymbol>.Enumerator enumerator2 = family.GetSymbols().GetEnumerator())
					{
						while (enumerator2.MoveNext())
						{
							FamilySymbol familySymbol = enumerator2.Current;
							if (familySymbol.Name == "开洞标记")
							{
								result = familySymbol;
								break;
							}
						}
						break;
					}
				}
			}
			return result;
		}

		public static FamilySymbol GetLinkSymbol(Autodesk.Revit.DB.Document doc)
		{
			FamilySymbol result = null;
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(Family)).ToElements())
			{
				Family family = element as Family;
				if (family != null && family.Name == "盈建科MEP开洞标记-链接")
				{
					using (List<FamilySymbol>.Enumerator enumerator2 = family.GetSymbols().GetEnumerator())
					{
						while (enumerator2.MoveNext())
						{
							FamilySymbol familySymbol = enumerator2.Current;
							if (familySymbol.Name == "盈建科MEP开洞标记-链接")
							{
								result = familySymbol;
								break;
							}
						}
						break;
					}
				}
			}
			return result;
		}

		public static FamilySymbol GetFloorSymbol(Autodesk.Revit.DB.Document doc)
		{
			FamilySymbol result = null;
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(Family)).ToElements())
			{
				Family family = element as Family;
				if (family != null && family.Name == "盈建科MEP开洞标记-楼板")
				{
					using (List<FamilySymbol>.Enumerator enumerator2 = family.GetSymbols().GetEnumerator())
					{
						while (enumerator2.MoveNext())
						{
							FamilySymbol familySymbol = enumerator2.Current;
							if (familySymbol.Name == "盈建科MEP开洞标记-楼板")
							{
								result = familySymbol;
								break;
							}
						}
						break;
					}
				}
			}
			return result;
		}

		public static Result AddOpeningTag(Autodesk.Revit.DB.Document doc, Element hostElem, XYZ xyz, int openingId)
		{
			Transaction transaction = new Transaction(doc, "AddOpeningTag");
			transaction.Start();
			Result result;
			try
			{
				FamilySymbol openingSymbol = CmdTools.GetOpeningSymbol(doc);
				UnifiedModified.ActivateFamilySymbol(openingSymbol);
				FamilyInstance familyInstance = doc.Create.NewFamilyInstance(xyz, openingSymbol, hostElem, (Autodesk.Revit.DB.Structure.StructuralType)0);
				transaction.Commit();
				Transaction transaction2 = new Transaction(doc, "SetOpeningTagMark");
				transaction2.Start();
				familyInstance.get_Parameter(BuiltInParameter.DOOR_NUMBER).Set(openingId.ToString());
				transaction2.Commit();
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Exception ex)
			{
				TaskDialog.Show("ex", ex.ToString());
				transaction.RollBack();
				result = Autodesk.Revit.UI.Result.Failed;
			}
			return result;
		}

		public static Result SetBallSymbol(Autodesk.Revit.DB.Document doc, XYZ xyz)
		{
			SubTransaction subTransaction = new SubTransaction(doc);
			subTransaction.Start();
			Result result;
			try
			{
				CmdTools.GetBallSymbol(doc);
				subTransaction.Commit();
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Exception)
			{
				subTransaction.RollBack();
				result = Autodesk.Revit.UI.Result.Failed;
			}
			return result;
		}

		public static Result SetLinkSymbol(Autodesk.Revit.DB.Document doc, XYZ xyz, Wall wall)
		{
			SubTransaction subTransaction = new SubTransaction(doc);
			subTransaction.Start();
			Result result;
			try
			{
				FamilySymbol linkSymbol = CmdTools.GetLinkSymbol(doc);
				UnifiedModified.ActivateFamilySymbol(linkSymbol);
				FamilyInstance familyInstance = doc.Create.NewFamilyInstance(xyz, linkSymbol, (Autodesk.Revit.DB.Structure.StructuralType)0);
				XYZ endOrDirection = new XYZ(1.0, 0.0, 0.0);
				Line line = doc.CreatYJKLine(xyz, endOrDirection, false);
				endOrDirection = new XYZ(0.0, 0.0, 1.0);
				line = doc.CreatYJKLine(xyz, endOrDirection, false);
				XYZ orientation = wall.Orientation;
				double num = new XYZ(1.0, 0.0, 0.0).AngleTo(orientation);
				if (orientation.Y < 0.0)
				{
					num = -num;
				}
				ElementTransformUtils.RotateElement(doc, familyInstance.Id, line, num);
				subTransaction.Commit();
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Exception)
			{
				subTransaction.RollBack();
				result = Autodesk.Revit.UI.Result.Failed;
			}
			return result;
		}

		public static Result SetFloorSymbol(Autodesk.Revit.DB.Document doc, XYZ xyz, Floor floor)
		{
			SubTransaction subTransaction = new SubTransaction(doc);
			subTransaction.Start();
			Result result;
			try
			{
				FamilySymbol floorSymbol = CmdTools.GetFloorSymbol(doc);
				UnifiedModified.ActivateFamilySymbol(floorSymbol);
				doc.Create.NewFamilyInstance(xyz, floorSymbol, (Autodesk.Revit.DB.Structure.StructuralType)0);
				subTransaction.Commit();
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Exception ex)
			{
				subTransaction.RollBack();
				TaskDialog.Show("info", ex.ToString());
				result = Autodesk.Revit.UI.Result.Failed;
			}
			return result;
		}

		public static void LoadOpeningSymbol(ExternalCommandData commandData)
		{
			UIApplication application = commandData.Application;
			Document document = application.ActiveUIDocument.Document;
			Selection selection = application.ActiveUIDocument.Selection;
			string str = Path.GetDirectoryName(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)) + "\\";
			Transaction transaction = new Transaction(document, "loadFamily");
			transaction.Start();
			document.LoadFamily(str + "Res\\盈建科MEP开洞检测.rfa");
			transaction.Commit();
		}

		public static void LoadBallSymbol(ExternalCommandData commandData)
		{
			UIApplication application = commandData.Application;
			Document document = application.ActiveUIDocument.Document;
			Selection selection = application.ActiveUIDocument.Selection;
			string str = Path.GetDirectoryName(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)) + "\\";
			Transaction transaction = new Transaction(document, "loadFamily");
			transaction.Start();
			document.LoadFamily(str + "Res\\盈建科MEP开洞标记.rfa");
			transaction.Commit();
		}

		public static void LoadLinkSymbol(ExternalCommandData commandData)
		{
			UIApplication application = commandData.Application;
			Document document = application.ActiveUIDocument.Document;
			Selection selection = application.ActiveUIDocument.Selection;
			string str = Path.GetDirectoryName(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)) + "\\";
			Transaction transaction = new Transaction(document, "loadFamily");
			transaction.Start();
			document.LoadFamily(str + "Res\\盈建科MEP开洞标记-链接.rfa");
			transaction.Commit();
		}

		public static void LoadFloorSymbol(ExternalCommandData commandData)
		{
			UIApplication application = commandData.Application;
			Document document = application.ActiveUIDocument.Document;
			Selection selection = application.ActiveUIDocument.Selection;
			string str = Path.GetDirectoryName(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)) + "\\";
			Transaction transaction = new Transaction(document, "loadFamily");
			transaction.Start();
			document.LoadFamily(str + "Res\\盈建科MEP开洞标记-楼板.rfa");
			transaction.Commit();
		}

		public static bool OpeningSymbolIsLoad(Autodesk.Revit.DB.Document doc)
		{
			bool result = false;
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(Family)).ToElements())
			{
				Family family = element as Family;
				if (family != null && family.Name == "盈建科MEP开洞检测")
				{
					result = true;
					break;
				}
			}
			return result;
		}

		public static bool BallSymbolIsLoad(Autodesk.Revit.DB.Document doc)
		{
			bool result = false;
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(Family)).ToElements())
			{
				Family family = element as Family;
				if (family != null && family.Name == "盈建科MEP开洞标记")
				{
					result = true;
					break;
				}
			}
			return result;
		}

		public static bool LinkSymbolIsLoad(Autodesk.Revit.DB.Document doc)
		{
			bool result = false;
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(Family)).ToElements())
			{
				Family family = element as Family;
				if (family != null && family.Name == "盈建科MEP开洞标记-链接")
				{
					result = true;
					break;
				}
			}
			return result;
		}

		public static bool FloorSymbolIsLoad(Autodesk.Revit.DB.Document doc)
		{
			bool result = false;
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(Family)).ToElements())
			{
				Family family = element as Family;
				if (family != null && family.Name == "盈建科MEP开洞标记-楼板")
				{
					result = true;
					break;
				}
			}
			return result;
		}

		public static int DeleteUselessRoundHole(Autodesk.Revit.DB.Document doc)
		{
			SubTransaction subTransaction = new SubTransaction(doc);
			subTransaction.Start();
			int num = 0;
			FamilyInstance familyInstance = null;
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(FamilyInstance)).ToElements())
			{
				familyInstance = (element as FamilyInstance);
				if (familyInstance != null && familyInstance.Symbol.Family.Name == "盈建科MEP圆形墙洞")
				{
					LocationPoint locationPoint = familyInstance.Location as LocationPoint;
					int num2 = 0;
					decimal d = 0m;
					foreach (object obj in familyInstance.Symbol.Parameters)
					{
						Parameter parameter = (Parameter)obj;
						if (parameter.Definition.Name == "半径")
						{
							if (decimal.TryParse(parameter.AsValueString(), out d))
							{
								num2 = int.Parse(Math.Ceiling(d).ToString());
								break;
							}
							break;
						}
					}
					XYZ xyz = locationPoint.Point + new XYZ(0.0, 0.0, 1.0) * (double)num2 / 304.8;
					List<Pipe> list = CmdTools.FindAllPipe(doc);
					bool flag = false;
					using (List<Pipe>.Enumerator enumerator3 = list.GetEnumerator())
					{
						while (enumerator3.MoveNext())
						{
							if (CmdTools.FindPipeCurve(enumerator3.Current).Distance(xyz) * 304.8 < 10.0)
							{
								flag = true;
							}
						}
					}
					foreach (Duct duct in CmdTools.FindRoundDuct(doc))
					{
						if (CmdTools.FindDuctCurve(duct).Distance(xyz) * 304.8 < CmdTools.GetDuctDiameter(duct))
						{
							flag = true;
						}
					}
					if (!flag)
					{
						doc.Delete(RevitVersionFuncs.GetElement(doc, familyInstance.Id).Id);
						num++;
					}
				}
			}
			subTransaction.Commit();
			return num;
		}

		public static int GetDuctAttr(Duct duct, string attrName)
		{
			int result = 0;
			decimal d = 0m;
			foreach (object obj in duct.Parameters)
			{
				Parameter parameter = (Parameter)obj;
				if (parameter.Definition.Name == attrName && decimal.TryParse(parameter.AsValueString(), out d))
				{
					result = int.Parse(Math.Ceiling(d).ToString());
				}
			}
			return result;
		}

		public static List<Pipe> FindAllPipe(Autodesk.Revit.DB.Document doc)
		{
			List<Pipe> list = new List<Pipe>();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			filteredElementCollector.OfClass(typeof(Pipe)).OfCategory(BuiltInCategory.OST_PipeCurves);
			foreach (Element element in filteredElementCollector)
			{
				Pipe pipe = element as Pipe;
				if (pipe != null)
				{
					list.Add(pipe);
				}
			}
			return list;
		}

		public static List<Wall> FindPipeWall(Autodesk.Revit.DB.Document doc, Pipe pipe)
		{
			return CmdTools.GetIntersectWallByPipe(pipe, doc);
		}

		public static List<Floor> FindPipeFloor(Autodesk.Revit.DB.Document doc, Pipe elemPipe)
		{
			return CmdTools.GetIntersectFloorByPipe(elemPipe, doc);
		}

		public static List<Wall> FindPipeWallLink(Autodesk.Revit.DB.Document doc, Pipe pipe, XYZ xyz)
		{
			return CmdTools.GetIntersectWallByPipe(pipe, doc);
		}

		public static List<Wall> FindPipeEquipmentLink(Autodesk.Revit.DB.Document doc, FamilyInstance fiHydrant, XYZ xyz)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			filteredElementCollector.OfClass(typeof(Wall));
			ElementIntersectsElementFilter elementIntersectsElementFilter = new ElementIntersectsElementFilter(fiHydrant);
			filteredElementCollector.WherePasses(elementIntersectsElementFilter);
			return filteredElementCollector.Cast<Wall>().ToList<Wall>();
		}

		public static List<Floor> FindPipeFloorLink(Autodesk.Revit.DB.Document doc, Pipe pipe, XYZ xyz)
		{
			return CmdTools.GetIntersectFloorByPipe(pipe, doc);
		}

		public static List<Solid> GetSolid(Element elem)
		{
			List<Solid> list = new List<Solid>();
			foreach (GeometryObject geometryObject in RevitVersionFuncs.GetGeometryObjectArray(elem.get_Geometry(new Options
			{
				ComputeReferences = true,
                DetailLevel = (ViewDetailLevel)2
			})))
			{
				if (geometryObject is GeometryInstance)
				{
					GeometryElement instanceGeometry = ((GeometryInstance)geometryObject).GetInstanceGeometry();
					new List<GeometryObject>();
					IEnumerator<GeometryObject> enumerator2 = instanceGeometry.GetEnumerator();
					while (enumerator2.MoveNext())
					{
						if (enumerator2.Current is Solid)
						{
							list.Add((Solid)enumerator2.Current);
						}
					}
				}
				else if (geometryObject is Solid)
				{
					list.Add((Solid)geometryObject);
				}
			}
			return list;
		}

		public static List<Face> GetWallFace(Wall wall)
		{
			List<Face> list = new List<Face>();
			foreach (GeometryObject geometryObject in RevitVersionFuncs.GetGeometryObjectArray(wall.get_Geometry(new Options
			{
				ComputeReferences = true,
                DetailLevel = (ViewDetailLevel)2
			})))
			{
				Solid solid = geometryObject as Solid;
				if (solid != null && solid.Faces.Size > 0)
				{
					foreach (object obj in solid.Faces)
					{
						Face face = (Face)obj;
						if (face is PlanarFace)
						{
							PlanarFace planarFace = face as PlanarFace;
							if (planarFace != null && planarFace.FaceNormal().AngleTo(wall.Orientation) < 0.01)
							{
								list.Add(face);
							}
						}
						else if (face is CylindricalFace && (face as CylindricalFace).Axis.Z > 0.0)
						{
							list.Add(face);
						}
					}
				}
			}
			return list;
		}

		public static Face FindFloorFace(Floor floor)
		{
			Face result = null;
			foreach (GeometryObject geometryObject in RevitVersionFuncs.GetGeometryObjectArray(floor.get_Geometry(new Options
			{
				ComputeReferences = true,
                DetailLevel = (ViewDetailLevel)2
			})))
			{
				Solid solid = geometryObject as Solid;
				if (solid != null && solid.Faces.Size > 0)
				{
					foreach (object obj in solid.Faces)
					{
						Face face = (Face)obj;
						if (face is PlanarFace)
						{
							if ((face as PlanarFace).FaceNormal().AngleTo(new XYZ(0.0, 0.0, 1.0)) < 0.01)
							{
								result = face;
							}
						}
						else if (face is CylindricalFace && (face as CylindricalFace).Axis.Z > 0.0)
						{
							result = face;
						}
					}
				}
			}
			return result;
		}

		private static List<Face> GetBeamFaces(FamilyInstance beam)
		{
			List<Face> list = new List<Face>();
			try
			{
				foreach (GeometryObject geometryObject in RevitVersionFuncs.GetGeometryObjectArray(beam.get_Geometry(new Options
				{
					ComputeReferences = true,
                    DetailLevel = (ViewDetailLevel)2
				})))
				{
					GeometryInstance geometryInstance = geometryObject as GeometryInstance;
					if (geometryInstance != null)
					{
						using (List<GeometryObject>.Enumerator enumerator2 = RevitVersionFuncs.GetGeometryObjectArray(geometryInstance.GetInstanceGeometry()).GetEnumerator())
						{
							while (enumerator2.MoveNext())
							{
								GeometryObject geometryObject2 = enumerator2.Current;
								if (geometryObject2 is Solid)
								{
									Solid solid = geometryObject2 as Solid;
									if (solid != null && solid.Faces.Size > 0)
									{
										foreach (object obj in solid.Faces)
										{
											Face face = (Face)obj;
											if (face is PlanarFace)
											{
												if ((face as PlanarFace).FaceNormal().AngleTo(beam.FacingOrientation) < 0.01)
												{
													list.Add(face);
												}
											}
											else if (face is CylindricalFace)
											{
												CylindricalFace cylindricalFace = face as CylindricalFace;
												if (cylindricalFace.Axis.Z > 0.0)
												{
													list.Add(cylindricalFace);
												}
											}
										}
									}
								}
							}
							continue;
						}
					}
					Solid solid2 = geometryObject as Solid;
					if (solid2 != null && solid2.Faces != null && solid2.Faces.Size != 0)
					{
						foreach (object obj2 in solid2.Faces)
						{
							Face face2 = (Face)obj2;
							if (face2 is PlanarFace)
							{
								if ((face2 as PlanarFace).FaceNormal().AngleTo(beam.FacingOrientation) < 0.01)
								{
									list.Add(face2);
								}
							}
							else if (face2 is CylindricalFace)
							{
								CylindricalFace cylindricalFace2 = face2 as CylindricalFace;
								if (cylindricalFace2.Axis.Z > 0.0)
								{
									list.Add(cylindricalFace2);
								}
							}
						}
					}
				}
			}
			catch
			{
			}
			return list;
		}

		public static List<Face> FindBeamFace(FamilyInstance beam)
		{
			return CmdTools.GetBeamFaces(beam);
		}

		public static Curve FindPipeCurve(Pipe pipe)
		{
			IList<XYZ> list = new List<XYZ>();
			ConnectorSetIterator connectorSetIterator = pipe.ConnectorManager.Connectors.ForwardIterator();
			while (connectorSetIterator.MoveNext())
			{
				object obj = connectorSetIterator.Current;
				Connector connector = obj as Connector;
				list.Add(connector.Origin);
			}
			return YJKLineEx.YJKGetBound(list.ElementAt(0), list.ElementAt(1));
		}

		public static Line FindPipeLine(Pipe pipe)
		{
			LocationCurve locationCurve = pipe.Location as LocationCurve;
			return YJKLineEx.YJKGetBound(locationCurve.Curve.GetEndPoint(0), locationCurve.Curve.GetEndPoint(1));
		}

		public static XYZ FindFaceCurve(Face face, Curve curve)
		{
			IntersectionResultArray intersectionResultArray = new IntersectionResultArray();
			SetComparisonResult setComparisonResult = face.Intersect(curve, out intersectionResultArray);
			XYZ result = null;
			if (4 != (int)setComparisonResult && !intersectionResultArray.IsEmpty)
			{
				result = intersectionResultArray.get_Item(0).XYZPoint;
			}
			return result;
		}

		public static List<XYZ> LineIntersectFace(Face face, Line line)
		{
			List<XYZ> list = new List<XYZ>();
			try
			{
				IntersectionResultArray intersectionResultArray = new IntersectionResultArray();
				SetComparisonResult setComparisonResult = face.Intersect(line, out intersectionResultArray);
				if (4 != (int)setComparisonResult && intersectionResultArray != null && !intersectionResultArray.IsEmpty)
				{
					for (int i = 0; i < intersectionResultArray.Size; i++)
					{
						list.Add(intersectionResultArray.get_Item(i).XYZPoint);
					}
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message);
			}
			return list;
		}

		public static XYZ LineIntersectPlaneFace(Face face, Line line)
		{
			List<XYZ> list = new List<XYZ>();
			try
			{
				IntersectionResultArray intersectionResultArray = new IntersectionResultArray();
				SetComparisonResult setComparisonResult = face.Intersect(line, out intersectionResultArray);
				if (4 != (int)setComparisonResult && intersectionResultArray != null && !intersectionResultArray.IsEmpty)
				{
					for (int i = 0; i < intersectionResultArray.Size; i++)
					{
						list.Add(intersectionResultArray.get_Item(i).XYZPoint);
					}
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message);
			}
			if (list.Count > 0)
			{
				return list[0];
			}
			return null;
		}

		public static double GetDuctDiameter(Duct duct)
		{
			return double.Parse(duct.get_Parameter(BuiltInParameter.RBS_CURVE_DIAMETER_PARAM).AsValueString());
		}

		public static double GetDuctWidth(Duct duct, Autodesk.Revit.DB.Document doc)
		{
			double val = 0.0;
			double num = 0.0;
			CmdTools.GetPipeSecSize(duct, ref val, ref num);
			return AssistFunc.feetToMM(val);
		}

		public static double GetDuctHeight(Duct duct, Autodesk.Revit.DB.Document doc)
		{
			double num = 0.0;
			double val = 0.0;
			CmdTools.GetPipeSecSize(duct, ref num, ref val);
			return AssistFunc.feetToMM(val);
		}

		public static List<Duct> FindRectDuct(Autodesk.Revit.DB.Document doc)
		{
			List<Duct> list = new List<Duct>();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			filteredElementCollector.OfClass(typeof(Duct)).OfCategory(BuiltInCategory.OST_DuctCurves);
			foreach (Element element in filteredElementCollector)
			{
				Duct duct = element as Duct;
				foreach (object obj in duct.ConnectorManager.Connectors)
				{
					Connector connector = (Connector)obj;
                    if ((int)connector.ConnectorType == 1 && (int)connector.Shape == 1)
					{
						list.Add(duct);
						break;
					}
				}
			}
			return list;
		}

		public static List<Wall> FindDuctWallLink(Duct duct, Autodesk.Revit.DB.Document docLink, XYZ xyz)
		{
			return CmdTools.GetIntersectWallByPipe(duct, docLink);
		}

		public static List<Wall> FindEquipWallLink(FamilyInstance fiEquip, Autodesk.Revit.DB.Document doc)
		{
			try
			{
				XYZ origin = fiEquip.GetTransform().Origin;
				XYZ facingOrientation = fiEquip.FacingOrientation;
				XYZ basisZ = XYZ.BasisZ;
				facingOrientation.CrossProduct(basisZ).Normalize();
				fiEquip.GetParameter("宽度").AsDouble();
				BoundingBoxXYZ boundingBoxXYZ = fiEquip.get_BoundingBox(doc.ActiveView);
				Outline outline = new Outline(boundingBoxXYZ.Min, boundingBoxXYZ.Max);
				FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
				BoundingBoxIntersectsFilter boundingBoxIntersectsFilter = new BoundingBoxIntersectsFilter(outline);
				List<Wall> list = filteredElementCollector.OfClass(typeof(Wall)).WherePasses(boundingBoxIntersectsFilter).Cast<Wall>().ToList<Wall>();
				List<Wall> list2 = new List<Wall>();
				XYZ xyz = new XYZ(origin.X, origin.Y, 0.0);
				foreach (Wall wall in list)
				{
					Curve elemLocationCurve = CmdTools.GetElemLocationCurve(wall);
					Transform transform = Transform.CreateTranslation(facingOrientation.Negate() * wall.Width * 0.5);
					Curve curve = elemLocationCurve.CreateTransformed(transform);
					Curve curve2 = Line.CreateUnbound(xyz, facingOrientation);
					IntersectionResultArray intersectionResultArray = null;
                    if ((int)curve2.Intersect(curve, out intersectionResultArray) == 8 && intersectionResultArray != null && intersectionResultArray.Size > 0)
					{
						XYZ xyzpoint = intersectionResultArray.get_Item(0).XYZPoint;
						double d = xyzpoint.DistanceTo(xyz);
						try
						{
							double d2 = fiEquip.GetParameter("下进水口距后面距离").AsDouble();
							XYZ firstVec = xyzpoint - xyz;
							if (GeoUtil.IsEqual(d, d2) && GeoUtil.IsSameDirection(firstVec, facingOrientation))
							{
								continue;
							}
						}
						catch
						{
							continue;
						}
						list2.Add(wall);
					}
				}
				return list2;
			}
			catch
			{
			}
			return new List<Wall>();
		}

		public static List<Face> GetEquipFaces(FamilyInstance fiEquip, Autodesk.Revit.DB.View view)
		{
			List<Face> list = new List<Face>();
			try
			{
				FaceArray faceArray = new FaceArray();
				CmdTools.GetGeometryElementPlaneFace(fiEquip.get_Geometry(new Options
				{
					ComputeReferences = true,
					View = view
				}), view, ref faceArray);
				foreach (object obj in faceArray)
				{
					Face item = (Face)obj;
					list.Add(item);
				}
			}
			catch
			{
			}
			return list;
		}

		public static void GetGeometryElementPlaneFace(GeometryElement elem, Autodesk.Revit.DB.View view, ref FaceArray arFaces)
		{
			foreach (GeometryObject geometryObject in RevitVersionFuncs.GetGeometryObjectArray(elem))
			{
				if (geometryObject is Solid)
				{
					IEnumerator enumerator2 = (geometryObject as Solid).Faces.GetEnumerator();
					{
						while (enumerator2.MoveNext())
						{
							object obj = enumerator2.Current;
							Face face = (Face)obj;
							if (!(face.GetType() != typeof(PlanarFace)))
							{
								arFaces.Append(face);
							}
						}
						continue;
					}
				}
				if (geometryObject is GeometryInstance)
				{
					CmdTools.GetGeometryElementPlaneFace((geometryObject as GeometryInstance).SymbolGeometry, view, ref arFaces);
				}
			}
		}

		public static OpeningStatus GetStatus(UIApplication uiApp, Element element, Autodesk.Revit.DB.Document docLink, XYZ xyz, XYZ location)
		{
			BoundingBoxXYZ boundingBoxXYZ = element.get_BoundingBox(docLink.ActiveView);
			BoundingBoxIntersectsFilter boundingBoxIntersectsFilter = new BoundingBoxIntersectsFilter(new Outline(boundingBoxXYZ.Min - xyz, boundingBoxXYZ.Max - xyz), false);
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(docLink);
			IList<Element> list = filteredElementCollector.OfClass(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_Doors).WherePasses(boundingBoxIntersectsFilter).ToElements();
			new FilteredElementCollector(docLink);
			foreach (Element item in filteredElementCollector.OfClass(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_Doors).WherePasses(boundingBoxIntersectsFilter).ToElements())
			{
				list.Add(item);
			}
			foreach (LinkFile linkFile in LinkFile.GetLinkFiles(uiApp.ActiveUIDocument.Document))
			{
				Document document = uiApp.Application.OpenDocumentFile(linkFile.FileName);
				foreach (Element item2 in new FilteredElementCollector(document).OfClass(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_Doors).WherePasses(boundingBoxIntersectsFilter).ToElements())
				{
					list.Add(item2);
				}
				foreach (Element item3 in new FilteredElementCollector(document).OfClass(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_Windows).WherePasses(boundingBoxIntersectsFilter).ToElements())
				{
					list.Add(item3);
				}
			}
			if (list.Count == 0)
			{
				return OpeningStatus.Unopen;
			}
			Solid solid = null;
			foreach (Element elem in list)
			{
				foreach (Solid solid2 in CmdTools.GetSolid(elem))
				{
					Solid solid3 = BooleanOperationsUtils.ExecuteBooleanOperation(CmdTools.GetSolid(element)[0], solid2, (Autodesk.Revit.DB.BooleanOperationsType)2);
					if (solid3.Volume > 0.0)
					{
						solid = solid3;
						break;
					}
				}
			}
            if (solid != null && (solid.Edges.get_Item(0).AsCurve().GetEndPoint(0) - location).GetLength() < 1.0)
			{
				return OpeningStatus.Invalid;
			}
			return OpeningStatus.Unopen;
		}

		public static List<FamilyInstance> FindElementIntersectBeam(Element elem, Autodesk.Revit.DB.Document doc, XYZ xyz)
		{
			List<FamilyInstance> list = new List<FamilyInstance>();
			BoundingBoxXYZ boundingBoxXYZ = elem.get_BoundingBox(doc.ActiveView);
			if (boundingBoxXYZ == null)
			{
				return list;
			}
			Outline outline = new Outline(boundingBoxXYZ.Min - xyz, boundingBoxXYZ.Max - xyz);
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			BoundingBoxIntersectsFilter boundingBoxIntersectsFilter = new BoundingBoxIntersectsFilter(outline, false);
			foreach (Element element in filteredElementCollector.OfClass(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_StructuralFraming).WherePasses(boundingBoxIntersectsFilter).ToElements())
			{
				FamilyInstance familyInstance = element as FamilyInstance;
				if (familyInstance != null)
				{
					list.Add(familyInstance);
				}
			}
			return list;
		}

		public static List<Floor> FindDuctFloorLink(Duct duct, Autodesk.Revit.DB.Document docLink, XYZ xyz)
		{
			return CmdTools.GetIntersectFloorByPipe(duct, docLink);
		}

		public static Curve FindDuctCurve(Duct duct)
		{
			IList<XYZ> list = new List<XYZ>();
			ConnectorSetIterator connectorSetIterator = duct.ConnectorManager.Connectors.ForwardIterator();
			while (connectorSetIterator.MoveNext())
			{
				object obj = connectorSetIterator.Current;
				Connector connector = obj as Connector;
				list.Add(connector.Origin);
			}
			Line line = YJKLineEx.YJKGetBound(list.ElementAt(0), list.ElementAt(1));
			line.MakeUnbound();
			return line;
		}

		public static Line GetDuctLine(Duct duct)
		{
			LocationCurve locationCurve = duct.Location as LocationCurve;
			return YJKLineEx.YJKGetBound(locationCurve.Curve.GetEndPoint(0), locationCurve.Curve.GetEndPoint(1));
		}

		public static XYZ FindWallVector(Wall wall)
		{
			LocationCurve locationCurve = wall.Location as LocationCurve;
			return locationCurve.Curve.GetEndPoint(1) - locationCurve.Curve.GetEndPoint(0);
		}

		public static List<Duct> FindRoundDuct(Autodesk.Revit.DB.Document doc)
		{
			List<Duct> list = new List<Duct>();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			filteredElementCollector.OfClass(typeof(Duct)).OfCategory(BuiltInCategory.OST_DuctCurves);
			foreach (Element element in filteredElementCollector)
			{
				Duct duct = element as Duct;
				foreach (object obj in duct.ConnectorManager.Connectors)
				{
					Connector connector = (Connector)obj;
					if ((int)connector.ConnectorType == 1 && connector.Shape == null)
					{
						list.Add(duct);
						break;
					}
				}
			}
			return list;
		}

		public static double GetDuctSpec(Duct duct)
		{
			double result = 0.0;
			Parameter parameter = duct.get_Parameter(BuiltInParameter.RBS_CURVE_DIAMETER_PARAM);
			if (parameter != null)
			{
				result = AssistFunc.feetToMM(parameter.AsDouble());
			}
			return result;
		}

		public static double GetPipeSpec(Pipe pipe)
		{
			return AssistFunc.feetToMM(pipe.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM).AsDouble());
		}

		public static List<double> FindDuctDiameter(Autodesk.Revit.DB.Document doc)
		{
			List<Duct> list = CmdTools.FindRoundDuct(doc);
			List<double> list2 = new List<double>();
			foreach (Duct duct in list)
			{
				double ductSpec = CmdTools.GetDuctSpec(duct);
				if (!list2.Contains(ductSpec))
				{
					list2.Add(ductSpec);
				}
			}
			return list2;
		}

		public static List<CableTray> FindAllCableTray(Autodesk.Revit.DB.Document doc)
		{
			List<CableTray> list = new List<CableTray>();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			filteredElementCollector.OfClass(typeof(CableTray)).OfCategory(BuiltInCategory.OST_CableTray);
			foreach (Element element in filteredElementCollector)
			{
				CableTray cableTray = element as CableTray;
				if (cableTray != null)
				{
					list.Add(cableTray);
				}
			}
			return list;
		}

		public static List<Wall> FindCableTrayWallLink(Autodesk.Revit.DB.Document doc, CableTray cableTray, XYZ xyz)
		{
			return CmdTools.GetIntersectWallByPipe(cableTray, doc);
		}

		public static List<Floor> FindCableTrayFloorLink(Autodesk.Revit.DB.Document doc, CableTray cableTray, XYZ xyz)
		{
			return CmdTools.GetIntersectFloorByPipe(cableTray, doc);
		}

		public static Line FindCableTrayLine(CableTray cableTray)
		{
			LocationCurve locationCurve = cableTray.Location as LocationCurve;
			return YJKLineEx.YJKGetBound(locationCurve.Curve.GetEndPoint(0), locationCurve.Curve.GetEndPoint(1));
		}

		public static bool GetPipeSecSize(MEPCurve elemPipe, ref double dW, ref double dH)
		{
			try
			{
				if (elemPipe is Duct)
				{
					Duct duct = (Duct)elemPipe;
					Parameter parameter = elemPipe.get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM);
					dW = parameter.AsDouble();
					Parameter parameter2 = elemPipe.get_Parameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM);
					dH = parameter2.AsDouble();
				}
				else if (elemPipe is CableTray)
				{
					CableTray cableTray = (CableTray)elemPipe;
					Parameter parameter3 = cableTray.get_Parameter(BuiltInParameter.RBS_CABLETRAY_WIDTH_PARAM);
					dW = parameter3.AsDouble();
					Parameter parameter4 = cableTray.get_Parameter(BuiltInParameter.RBS_CABLETRAY_HEIGHT_PARAM);
					dH = parameter4.AsDouble();
				}
				else
				{
					if (!(elemPipe is Pipe))
					{
						throw new Exception("无效的实体类型!");
					}
					Parameter parameter5 = ((Pipe)elemPipe).get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM);
					dW = parameter5.AsDouble();
					dH = -1.0;
				}
			}
			catch
			{
				return false;
			}
			return true;
		}

		public static XYZ CalcProjPointByPlane(XYZ ptTest, Plane planeProj)
		{
			return (Transform.CreateReflection(planeProj).OfPoint(ptTest) + ptTest) * 0.5;
		}

		public static double GetPipe2WallHAng(XYZ ptS, XYZ ptE, Wall wall, XYZ pt)
		{
			XYZ basisZ = XYZ.BasisZ;
			XYZ xyz = ptE - ptS;
			Plane planeProj = RevitVersionFuncs.CreatePlanByNormalAndOrigin(basisZ, pt);
			XYZ xyz2 = CmdTools.CalcProjPointByPlane(pt + xyz, planeProj) - pt;
			XYZ xyz3 = wall.Orientation;
			Arc arc = CmdTools.GetElemLocationCurve(wall) as Arc;
			if (arc != null)
			{
				XYZ xyz4 = CmdTools.CalcProjPointByPlane(arc.Center, planeProj);
				xyz3 = pt - xyz4;
			}
			return xyz3.AngleOnPlaneTo(xyz2, basisZ);
		}

		public static double GetPipe2WallVAng(XYZ ptS, XYZ ptE, Wall wall, XYZ pt)
		{
			XYZ basisZ = XYZ.BasisZ;
			XYZ xyz = ptE - ptS;
			Plane planeProj = RevitVersionFuncs.CreatePlanByNormalAndOrigin(xyz.CrossProduct(basisZ).Normalize(), pt);
			XYZ xyz2 = CmdTools.CalcProjPointByPlane(pt + wall.Orientation, planeProj) - pt;
			XYZ xyz3 = xyz2.CrossProduct(basisZ).Normalize();
			double num = xyz2.DotProduct(xyz);
			int num2 = -1;
			if (num >= 0.0)
			{
				num2 = 1;
			}
			xyz3 *= (double)num2;
			return xyz2.AngleOnPlaneTo(xyz, xyz3);
		}

		public static double R2A(double dAngR)
		{
			return dAngR * 180.0 / Math.PI;
		}

		private static Element GetElemByDoc(Autodesk.Revit.DB.Document doc, Type typeElem)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			filteredElementCollector.OfClass(typeElem);
			IList<Element> list = filteredElementCollector.ToList<Element>();
			if (list.Count > 0)
			{
				return list[0];
			}
			return null;
		}

		private static Curve GetElemLocationCurve(Element elem)
		{
			if (elem == null)
			{
				return null;
			}
			LocationCurve locationCurve = elem.Location as LocationCurve;
			if (locationCurve == null)
			{
				return null;
			}
			return locationCurve.Curve;
		}

		private static bool GetElemLocationCurve(Element elem, ref XYZ ptStart, ref XYZ ptEnd)
		{
			Curve elemLocationCurve = CmdTools.GetElemLocationCurve(elem);
			if (elemLocationCurve != null)
			{
				ptStart = elemLocationCurve.GetEndPoint(0);
				ptEnd = elemLocationCurve.GetEndPoint(1);
				return true;
			}
			return false;
		}

		public static List<XYZ> GetCvIntersect2WallPoints(Curve cv, Wall wall)
		{
			List<XYZ> list = new List<XYZ>();
			try
			{
				XYZ endPoint = cv.GetEndPoint(0);
				XYZ endPoint2 = cv.GetEndPoint(1);
				XYZ zero = XYZ.Zero;
				XYZ zero2 = XYZ.Zero;
				if (CmdTools.GetElemLocationCurve(wall, ref zero, ref zero2))
				{
					double z = zero.Z;
					XYZ xyz = new XYZ(endPoint.X, endPoint.Y, z);
					XYZ xyz2 = new XYZ(endPoint2.X, endPoint2.Y, z);
					Curve curve = Line.CreateBound(xyz, xyz2);
					IntersectionResultArray intersectionResultArray = null;
					Curve elemLocationCurve = CmdTools.GetElemLocationCurve(wall);
                    if ((int)curve.Intersect(elemLocationCurve, out intersectionResultArray) == 8)
					{
						for (int i = 0; i < intersectionResultArray.Size; i++)
						{
							XYZ xyzpoint = intersectionResultArray.get_Item(i).XYZPoint;
							Curve curve2 = Line.CreateUnbound(xyzpoint, XYZ.BasisZ);
							IntersectionResultArray intersectionResultArray2 = null;
                            if ((int)curve2.Intersect(cv, out intersectionResultArray2) == 8 && intersectionResultArray2.Size > 0)
							{
								xyzpoint = intersectionResultArray2.get_Item(0).XYZPoint;
								list.Add(xyzpoint);
							}
						}
					}
				}
			}
			catch
			{
			}
			return list;
		}

		public static FamilySymbol CreateFamilySymbolByTemplate(Family family, string strFamilyName, double dHAng, double dVAng, DbOpeningBase opening)
		{
			try
			{
				FamilySymbol familySymbol = null;
				Document document = family.Document;
				Document document2 = document.EditFamily(family);
				if (document2 == null)
				{
					throw new Exception("编辑族文档发生错误!");
				}
				Wall wall = CmdTools.GetElemByDoc(document2, typeof(Wall)) as Wall;
				if (wall == null)
				{
					throw new Exception("读取族文件中的实体发生错误!");
				}
				double z = CmdTools.GetElemLocationCurve(wall).GetEndPoint(0).Z;
				Sweep sweep = CmdTools.GetElemByDoc(document2, typeof(Sweep)) as Sweep;
				if (sweep == null)
				{
					throw new Exception("读取族文件中的实体发生错误!");
				}
				CurveArrArray profile = sweep.PathSketch.Profile;
				if (profile.Size < 1)
				{
					throw new Exception("读取族文件中的实体发生错误!");
				}
                CurveArray curveArray = profile.get_Item(0);
				if (curveArray.Size < 1)
				{
					throw new Exception("读取族文件中的实体发生错误!");
				}
                Curve curve = curveArray.get_Item(0);
				if (curve == null)
				{
					throw new Exception("读取族文件中的实体发生错误!");
				}
				Element element = sweep;
				Transaction transaction = new Transaction(document2, "ModifyParam");
				transaction.Start();
				try
				{
					FamilyManager familyManager = document2.FamilyManager;
					double parameter = opening.BoxParameter.Parameter1;
					if (opening.SectionParameter.SectionType == DBService.SectionType.Rect)
					{
						FamilyParameter familyParameter = familyManager.get_Parameter("洞口宽度");
						familyManager.Set(familyParameter, AssistFunc.mmToFeet(opening.SectionParameter.Parameter2 + parameter * 2.0));
						FamilyParameter familyParameter2 = familyManager.get_Parameter("洞口高度");
						familyManager.Set(familyParameter2, AssistFunc.mmToFeet(opening.SectionParameter.Parameter1 + parameter * 2.0));
					}
					else
					{
						FamilyParameter familyParameter3 = familyManager.get_Parameter("洞口半径");
						familyManager.Set(familyParameter3, AssistFunc.mmToFeet(opening.SectionParameter.Parameter1 * 0.5 + parameter));
					}
					transaction.Commit();
				}
				catch
				{
					transaction.RollBack();
				}
				Transaction transaction2 = new Transaction(document2, "DelRestrict");
				transaction2.Start();
				try
				{
					IList<Element> list = new FilteredElementCollector(document2).OfClass(typeof(Dimension)).ToElements();
					int count = list.Count;
					for (int i = 0; i < count; i++)
					{
						Dimension dimension = list[i] as Dimension;
						if (dimension.NumberOfSegments == 2)
						{
							document2.Delete(dimension.Id);
						}
					}
					transaction2.Commit();
				}
				catch
				{
					transaction2.RollBack();
				}
				List<XYZ> cvIntersect2WallPoints = CmdTools.GetCvIntersect2WallPoints(curve, wall);
				if (cvIntersect2WallPoints.Count < 1)
				{
					throw new Exception("读取族文件中的实体发生错误!");
				}
				XYZ xyz = cvIntersect2WallPoints[0];
				Transaction transaction3 = new Transaction(document2, "RotateElement");
				transaction3.Start();
				try
				{
					XYZ basisZ = XYZ.BasisZ;
					Line line = Line.CreateUnbound(xyz, XYZ.BasisX);
					ElementTransformUtils.RotateElement(document2, element.Id, line, dVAng);
					Line line2 = Line.CreateUnbound(xyz, basisZ);
					ElementTransformUtils.RotateElement(document2, element.Id, line2, dHAng);
					transaction3.Commit();
				}
				catch
				{
					transaction3.RollBack();
				}
				CmdTools.MyFamilyLoadOptions myFamilyLoadOptions = new CmdTools.MyFamilyLoadOptions();
				Family family2 = document2.LoadFamily(document, myFamilyLoadOptions);
				Transaction transaction4 = new Transaction(document, "ReNameFamily");
				try
				{
					transaction4.Start();
					family2.Name = strFamilyName;
					transaction4.Commit();
				}
				catch
				{
					transaction4.RollBack();
				}
				document2.Close(false);
				if (family2 != null)
				{
					familySymbol = family2.GetSymbols().FirstOrDefault<FamilySymbol>();
					Transaction transaction5 = new Transaction(document, "ModifyFiSymbolName");
					transaction5.Start();
					try
					{
						familySymbol.Name = strFamilyName;
						transaction5.Commit();
					}
					catch
					{
						transaction5.RollBack();
					}
				}
				return familySymbol;
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message);
			}
			return null;
		}

		public static FamilySymbol CreateFamilySymbolByTemplate(Family family, string strFiSymbolName, DbOpeningBase opening)
		{
			FamilySymbol familySymbol = null;
			Document document = family.Document;
			Document document2 = null;
			try
			{
				document2 = document.EditFamily(family);
				if (document2 == null)
				{
					throw new Exception("编辑族文档发生错误!");
				}
				if (!(CmdTools.GetElemByDoc(document2, typeof(Floor)) is Floor))
				{
					throw new Exception("读取族文件中的实体发生错误!");
				}
				Sweep sweep = CmdTools.GetElemByDoc(document2, typeof(Sweep)) as Sweep;
				if (sweep == null)
				{
					throw new Exception("读取族文件中的实体发生错误!");
				}
				CurveArrArray profile = sweep.PathSketch.Profile;
				if (profile.Size < 1)
				{
					throw new Exception("读取族文件中的实体发生错误!");
				}
                CurveArray curveArray = profile.get_Item(0);
				if (curveArray.Size < 1)
				{
					throw new Exception("读取族文件中的实体发生错误!");
				}
                if (curveArray.get_Item(0) == null)
				{
					throw new Exception("读取族文件中的实体发生错误!");
				}
				Element element = sweep;
				Transaction transaction = new Transaction(document2, "ModifyParam");
				transaction.Start();
				try
				{
					double num = opening.BoxParameter.Parameter1 * 2.0;
					double num2 = AssistFunc.mmToFeet(opening.SectionParameter.Parameter2 + num);
					double num3 = AssistFunc.mmToFeet(opening.SectionParameter.Parameter1 + num);
					FamilyManager familyManager = document2.FamilyManager;
					if (opening.SectionParameter.SectionType == DBService.SectionType.Arc)
					{
						FamilyParameter familyParameter = familyManager.get_Parameter("洞口直径");
						familyManager.Set(familyParameter, num3);
					}
					else
					{
						FamilyParameter familyParameter2 = familyManager.get_Parameter("洞口宽度");
						familyManager.Set(familyParameter2, num2);
						FamilyParameter familyParameter3 = familyManager.get_Parameter("洞口高度");
						familyManager.Set(familyParameter3, num3);
					}
					transaction.Commit();
				}
				catch
				{
					transaction.RollBack();
				}
				Transaction transaction2 = new Transaction(document2, "DelRestrict");
				transaction2.Start();
				try
				{
					IList<Element> list = new FilteredElementCollector(document2).OfClass(typeof(Dimension)).ToElements();
					int count = list.Count;
					for (int i = 0; i < count; i++)
					{
						Dimension dimension = list[i] as Dimension;
						if (dimension.NumberOfSegments == 2)
						{
							document2.Delete(dimension.Id);
						}
					}
					transaction2.Commit();
				}
				catch
				{
					transaction2.RollBack();
				}
				XYZ zero = XYZ.Zero;
				Transaction transaction3 = new Transaction(document2, "RotateElement");
				transaction3.Start();
				try
				{
					Line line = Line.CreateUnbound(zero, XYZ.BasisZ);
					ElementTransformUtils.RotateElement(document2, element.Id, line, opening.PipeConnAxisXOnSectionPlaneAng);
					transaction3.Commit();
				}
				catch
				{
					transaction3.RollBack();
				}
				CmdTools.MyFamilyLoadOptions myFamilyLoadOptions = new CmdTools.MyFamilyLoadOptions();
				Family family2 = document2.LoadFamily(document, myFamilyLoadOptions);
				Transaction transaction4 = new Transaction(document, "ReNameFamily");
				transaction4.Start();
				try
				{
					family2.Name = strFiSymbolName;
					transaction4.Commit();
				}
				catch
				{
					transaction4.RollBack();
				}
				document2.Close(false);
				if (family2 != null)
				{
					familySymbol = family2.GetSymbols().FirstOrDefault<FamilySymbol>();
					Transaction transaction5 = new Transaction(document, "ModifyFiSymbolName");
					transaction5.Start();
					try
					{
						familySymbol.Name = strFiSymbolName;
						transaction5.Commit();
					}
					catch
					{
						transaction5.RollBack();
					}
				}
			}
			catch
			{
				if (document2 != null)
				{
					document2.Close(false);
				}
			}
			return familySymbol;
		}

		public static double GetMEPCurveAng2Floor(MEPCurve elemPipe, Floor floor)
		{
			try
			{
				XYZ xyz = null;
				XYZ xyz2 = null;
				ConnectorSetIterator connectorSetIterator = elemPipe.ConnectorManager.Connectors.ForwardIterator();
				while (connectorSetIterator.MoveNext())
				{
					object obj = connectorSetIterator.Current;
					Connector connector = obj as Connector;
					if (connector != null && connector.CoordinateSystem.BasisZ.IsAlmostEqualTo(XYZ.BasisZ))
					{
						xyz2 = connector.CoordinateSystem.BasisX;
						XYZ basisY = connector.CoordinateSystem.BasisY;
						xyz = connector.CoordinateSystem.BasisZ;
						break;
					}
				}
				if (xyz == null)
				{
					throw new Exception("非有效楼板开洞管道实体!");
				}
				return XYZ.BasisX.AngleOnPlaneTo(xyz2, xyz);
			}
			catch
			{
			}
			return 0.0;
		}

		public static List<Wall> GetIntersectWallByPipe(MEPCurve elemPipe, Autodesk.Revit.DB.Document doc)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			filteredElementCollector.OfClass(typeof(Wall));
			ElementIntersectsElementFilter elementIntersectsElementFilter = new ElementIntersectsElementFilter(elemPipe);
			filteredElementCollector.WherePasses(elementIntersectsElementFilter);
			return filteredElementCollector.Cast<Wall>().ToList<Wall>();
		}

		public static List<Floor> GetIntersectFloorByPipe(MEPCurve elemPipe, Autodesk.Revit.DB.Document doc)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			filteredElementCollector.OfClass(typeof(Floor));
			ElementIntersectsElementFilter elementIntersectsElementFilter = new ElementIntersectsElementFilter(elemPipe);
			filteredElementCollector.WherePasses(elementIntersectsElementFilter);
			return filteredElementCollector.Cast<Floor>().ToList<Floor>();
		}

		public static GraphicsStyle GetOpening2DLineStyle(Autodesk.Revit.DB.Document doc)
		{
			string text = "洞口二维符族号轮廓线";
			Category category = doc.Settings.Categories.get_Item(BuiltInCategory.OST_Lines);
			if (category == null)
			{
				return null;
			}
			if (!category.SubCategories.Contains(text))
			{
				Transaction transaction = new Transaction(doc);
				try
				{
					transaction.Start("new line style");
					Category category2 = doc.Settings.Categories.NewSubcategory(category, text);
                    category2.LineColor = new Autodesk.Revit.DB.Color(0, 0, 0);
					category2.SetLineWeight(10, (Autodesk.Revit.DB.GraphicsStyleType)1);
					transaction.Commit();
				}
				catch (Exception)
				{
					if (transaction != null && transaction.HasStarted() && !transaction.HasEnded())
					{
						transaction.RollBack();
					}
					return null;
				}
			}
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(GraphicsStyle)))
			{
				GraphicsStyle graphicsStyle = element as GraphicsStyle;
				if (graphicsStyle.Name.CompareTo(text) == 0)
				{
					return graphicsStyle;
				}
			}
			return null;
		}

		public static LinePatternElement GetOpening2DLineStylePattern(Autodesk.Revit.DB.Document doc)
		{
			string text = "洞口二维符族号轮廓线线型图案";
			LinePatternElement linePatternElement = LinePatternElement.GetLinePatternElementByName(doc, text);
			if (linePatternElement == null)
			{
				List<LinePatternSegment> list = new List<LinePatternSegment>();
				list.Add(new LinePatternSegment((LinePatternSegmentType)0, AssistFunc.mmToFeet(2.0)));
				list.Add(new LinePatternSegment((LinePatternSegmentType)1, AssistFunc.mmToFeet(1.0)));
				LinePattern linePattern = new LinePattern(text);
				linePattern.SetSegments(list);
				Transaction transaction = new Transaction(doc);
				transaction.Start("Create a linepattern element");
				try
				{
					linePatternElement = LinePatternElement.Create(doc, linePattern);
					transaction.Commit();
				}
				catch
				{
					transaction.RollBack();
				}
			}
			return linePatternElement;
		}

		public static FilledRegionType GetOpening2DFilledRegionType(Autodesk.Revit.DB.Document doc)
		{
			string text = "HYOpening2DFilledRegionType";
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc).OfClass(typeof(FilledRegionType));
			FilledRegionType filledRegionType = null;
			FilledRegionType filledRegionType2 = null;
			foreach (Element element in filteredElementCollector)
			{
				FilledRegionType filledRegionType3 = element as FilledRegionType;
				if (filledRegionType2 == null)
				{
					filledRegionType = filledRegionType3;
				}
				if (filledRegionType3.Name.CompareTo(text) == 0)
				{
					filledRegionType2 = filledRegionType3;
					break;
				}
			}
			if (filledRegionType2 != null)
			{
				return filledRegionType2;
			}
			if (filledRegionType == null)
			{
				return null;
			}
			FillPatternElement solidPattern = CmdTools.GetSolidPattern("实体填充", doc);
			if (solidPattern == null)
			{
				return null;
			}
			Transaction transaction = new Transaction(doc, "CopyFilledRegionType");
			try
			{
				transaction.Start();
				filledRegionType2 = (filledRegionType.Duplicate(text) as FilledRegionType);
				filledRegionType2.FillPatternId = solidPattern.Id;
                filledRegionType2.Color = new Autodesk.Revit.DB.Color(byte.MaxValue, byte.MaxValue, byte.MaxValue);
				transaction.Commit();
			}
			catch
			{
				transaction.RollBack();
			}
			return filledRegionType2;
		}

		public static List<FamilyInstance> FindAllFireHydrant(Autodesk.Revit.DB.Document doc)
		{
			return new FilteredElementCollector(doc).OfClass(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_MechanicalEquipment).Cast<FamilyInstance>().ToList<FamilyInstance>();
		}

		private static FillPatternElement GetSolidPattern(string patternName, Autodesk.Revit.DB.Document doc)
		{
			return new FilteredElementCollector(doc).OfClass(typeof(FillPatternElement)).Cast<FillPatternElement>().FirstOrDefault<FillPatternElement>();
		}

		private static Schema CreateSchema(Autodesk.Revit.DB.Document doc, Guid schemaGuid, int id)
		{
			Schema schema = Schema.Lookup(schemaGuid);
			if (schema == null)
			{
				Transaction transaction = new Transaction(doc, "CreateSchema");
				try
				{
					transaction.Start();
					SchemaBuilder schemaBuilder = new SchemaBuilder(schemaGuid);
					schemaBuilder.SetSchemaName("OpeningID");
					schemaBuilder.AddSimpleField("ID", typeof(int));
					schema = schemaBuilder.Finish();
					transaction.Commit();
				}
				catch
				{
					transaction.RollBack();
				}
			}
			return schema;
		}

		public static void WriteToElement(Element elem, Guid schemaGuid, int id)
		{
			if (elem == null)
			{
				return;
			}
			Document document = elem.Document;
			Schema.Lookup(schemaGuid);
			Transaction transaction = new Transaction(document, "WriteExtensibleStorage");
			Schema schema = CmdTools.CreateSchema(document, schemaGuid, id);
			if (schema != null && schema.SchemaName == "OpeningID")
			{
				try
				{
					transaction.Start();
					Entity entity = new Entity(schema);
					Field field = schema.GetField("ID");
					entity.Set<int>(field, id);
					elem.SetEntity(entity);
					transaction.Commit();
				}
				catch
				{
					transaction.RollBack();
				}
			}
		}

		public static int ReadFromElement(Element elem, Guid schemaGuid)
		{
			Schema schema = Schema.Lookup(schemaGuid);
			if (schema != null)
			{
				Entity entity = elem.GetEntity(schema);
				if (entity != null)
				{
					Field field = schema.GetField("ID");
					return entity.Get<int>(field);
				}
			}
			return 0;
		}

		public static bool IsPrimaryStructure(ElementId idHost, Autodesk.Revit.DB.Document doc)
		{
			try
			{
				Element element = doc.GetElement(idHost);
				int integerValue = element.Category.Id.IntegerValue;
				if (integerValue == -2001320 || integerValue == -2000032)
				{
					return true;
				}
				if (integerValue == -2000011)
				{
					Wall wall = element as Wall;
					Parameter parameter = wall.GetParameter(BuiltInParameter.WALL_STRUCTURAL_SIGNIFICANT);
					if (parameter != null && parameter.AsInteger() == 1)
					{
						return true;
					}
					foreach (ElementId elementId in wall.GetMaterialIds(false))
					{
						Material material = doc.GetElement(elementId) as Material;
						if (material != null)
						{
							string name = material.Name;
							if (Regex.IsMatch(name, "钢筋混凝土") || Regex.IsMatch(name, "砼"))
							{
								return true;
							}
							if (Regex.IsMatch(name, "混凝土") && !name.Contains("蒸汽加气混凝土") && !name.Contains("轻集料混凝土") && !name.Contains("混凝土小型空心砌块") && !name.Contains("素混凝土") && !name.Contains("陶粒混凝土"))
							{
								return true;
							}
						}
					}
				}
			}
			catch
			{
			}
			return false;
		}

		public static DbOpeningBase CreateEquipWallOpening(Wall wall, FamilyInstance fiEquip)
		{
			LocationCurve locationCurve = wall.Location as LocationCurve;
			if (locationCurve.Curve is Arc)
			{
				return null;
			}
			try
			{
				Document document = fiEquip.Document;
				string mepfileName = XmlUtils.SplitPathName(document.PathName);
				List<Extrusion> list = new FilteredElementCollector(document.EditFamily(fiEquip.Symbol.Family)).OfClass(typeof(Extrusion)).Cast<Extrusion>().ToList<Extrusion>();
				Extrusion extrusion = null;
				foreach (Extrusion extrusion2 in list)
				{
					if (GeoUtil.IsParallel(extrusion2.Sketch.SketchPlane.GetPlane().Normal, XYZ.BasisZ))
					{
						extrusion = extrusion2;
						break;
					}
				}
				if (extrusion == null)
				{
					return null;
				}
				Line line = locationCurve.Curve as Line;
				if (line != null)
				{
					XYZ xyz = line.GetEndPoint(0);
					XYZ xyz2 = line.GetEndPoint(1);
					xyz = new XYZ(xyz.X, xyz.Y, 0.0);
					xyz2 = new XYZ(xyz2.X, xyz2.Y, 0.0);
					line = Line.CreateBound(xyz, xyz2);
					double val = fiEquip.GetParameter("长度").AsDouble();
					double val2 = fiEquip.GetParameter("高度").AsDouble();
					double num = fiEquip.GetParameter("下进水口距后面距离").AsDouble();
					XYZ xyz3 = fiEquip.FacingOrientation * -1.0;
					Transform transform = Transform.CreateTranslation(xyz3 * wall.Width * 0.5);
					line = (line.CreateTransformed(transform) as Line);
					XYZ origin = fiEquip.GetTransform().Origin;
					XYZ xyz4 = new XYZ(origin.X, origin.Y, 0.0);
					Line line2 = Line.CreateUnbound(xyz4, xyz3);
					IntersectionResultArray intersectionResultArray = null;
                    if ((int)line.Intersect(line2, out intersectionResultArray) == 8 && intersectionResultArray != null && intersectionResultArray.Size > 0)
					{
						XYZ xyzpoint = intersectionResultArray.get_Item(0).XYZPoint;
						XYZ firstVec = xyzpoint - xyz4;
						double num2 = xyz4.DistanceTo(xyzpoint);
						if (!GeoUtil.IsSameDirection(firstVec, xyz3))
						{
							num2 *= -1.0;
						}
						XYZ xyz5 = new XYZ(xyzpoint.X, xyzpoint.Y, origin.Z);
						xyz5 += XYZ.BasisZ * extrusion.StartOffset;
						num2 += num;
						SectionParameter sp = new SectionParameter(AssistFunc.feetToMM(val2), AssistFunc.feetToMM(val));
						HostType hostType = HostType.eStruWall;
						if (wall.get_Parameter(BuiltInParameter.WALL_STRUCTURAL_SIGNIFICANT).AsInteger() == 0)
						{
							hostType = HostType.eArchWall;
						}
						RectOutSize rectOutSize = XmlUtils.GetRectOutSize(CutType.eOther, hostType);
						BoxParameter bp = new BoxParameter(rectOutSize.Top, rectOutSize.Bottom, rectOutSize.Left, rectOutSize.Right);
						return new DbWallToBeOpened(-1, xyz5, wall.Id.IntegerValue, ElementId.InvalidElementId.IntegerValue, sp, bp, CutType.eOther, hostType, wall.GetYJKLevel().Name)
						{
							Status = OpeningStatus.Unopen,
							bEquipOpening = true,
							MEPFileName = mepfileName,
							OpeningID = ElementId.InvalidElementId,
							PipeStartPoint = origin + wall.Orientation * 1.0,
							PipeEndPoint = origin - wall.Orientation * 1.0,
							dWallWidth = wall.WallType.Width,
							vtWallOrient = xyz3,
							dOpeningThickness = AssistFunc.feetToMM(num2)
						};
					}
				}
			}
			catch
			{
			}
			return null;
		}

		public class MyFamilyLoadOptions : IFamilyLoadOptions
		{
			bool IFamilyLoadOptions.OnFamilyFound(bool familyInUse, out bool overwriteParameterValues)
			{
				overwriteParameterValues = true;
				return true;
			}

			bool IFamilyLoadOptions.OnSharedFamilyFound(Family sharedFamily, bool familyInUse, out FamilySource source, out bool overwriteParameterValues)
			{
				source = 0;
				overwriteParameterValues = true;
				return true;
			}
		}
	}
}
